package com.hb.B_面向对象.clazz

class Demo01 {
}

/**
 * Kotlin 中使用关键字 class 声明类.
 *
 * 类声明由类名、类头（指定其类型参数、主构造函数等）以及由花括号包围的类体构成。类头与类体都是可选的；
 * 如果一个类没有类体，可以省略花括号。
 *
 * 构造函数:
 * 在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。
 * 主构造函数是类头的一部分：它跟在类名（与可选的类型参数）后。
 */
class Invoice { /*……*/ }

//带主构造函数的类声明
class Person1 constructor(firstName: String) { /*……*/ }

//如果主构造函数没有任何注解或者可见性修饰符，可以省略这个 constructor 关键字。
class Person2(firstName: String) { /*……*/ }

//主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块（initializer blocks）中。
//在实例初始化期间，初始化块按照它们出现在类体中的顺序执行，与属性初始化器交织在一起：
class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)

    init {
        println("First initializer block that prints ${name}")
    }

    val secondProperty = "Second property: ${name.length}".also(::println)

    init {
        println("Second initializer block that prints ${name.length}")
    }
    //请注意，主构造的参数可以在初始化块中使用。它们也可以在类体内声明的属性初始化器中使用：
    val upperName = name.toUpperCase()

}
//事实上，声明属性以及从主构造函数初始化属性，Kotlin 有简洁的语法
class Person(val firstName: String, val lastName: String, var age: Int) { /*……*/ }


/**
 * 与普通属性一样，主构造函数中声明的属性可以是可变的（var）或只读的（val）。
 * 如果构造函数有注解或可见性修饰符，这个 constructor 关键字是必需的，并且这些修饰符在它前面：
 *
 */
//class Customer public @Inject constructor(name: String) { /*……*/ }


/**
 * 创建类的实例
 * 要创建一个类的实例，我们就像普通函数一样调用构造函数：
 * val invoice = Invoice()
 * val customer = Customer("Joe Smith")
 * 注意 Kotlin 并没有 new 关键字。
 * 创建嵌套类、内部类与匿名内部类的类实例在嵌套类中有述。
 */

/**
 * 类成员：
 * - 构造函数与初始化块
 * - 函数
 * - 属性
 * - 嵌套类与内部类
 * - 对象声明
 */

/**
 * 继承
 * 在 Kotlin 中所有类都有一个共同的超类 Any，这对于没有超类型声明的类是默认超类：
 * Any 有三个方法：equals()、 hashCode() 与 toString()。因此，为所有 Kotlin 类都定义了这些方法。
 * 默认情况下，Kotlin 类是最终（final）的：它们不能被继承。 要使一个类可继承，请用 open 关键字标记它。
 *
 * 如果派生类有一个主构造函数，其基类可以（并且必须） 用派生类主构造函数的参数就地初始化。
 * 如果派生类没有主构造函数，那么每个次构造函数必须使用 super 关键字初始化其基类型，或委托给另一个构造函数做到这一点。
 * 注意，在这种情况下，不同的次构造函数可以调用基类型的不同的构造函数：
 */
 class son(num:Int):father(num){

}
open class father(num:Int){

}

fun main() {
    val initOrderDemo = InitOrderDemo("hello")
    println(initOrderDemo.upperName)

}